#include "Aux_cmd_define.h"
#include "Aux_yate_hal.h"
#include <functional>

//=====================================================================================================================
//=====================================================================================================================
//=====================================================================================================================
//=====================================================================================================================

using namespace TelEngine;


namespace {	 // 使用匿名空间


	//===============================
	// 类定义


	class MyPlugin : public Plugin
	{
	public:


		MyPlugin() : Plugin("demo01")
			, m_initialized(false) 
		{
			
		}


		~MyPlugin() {

		}

		virtual void initialize(void);

		void onEngineStart();
		void onEngineStop();

		bool onYateMessage(Message& msg);
		bool onDemoMessage(Message& msg);

		bool unload();

	private:

		bool m_initialized;

		YateMsgHandler* _debug_hdl=0;

		// debug消息
		bool onYateDebug(Message& msg);

	protected:
		std::vector<MessageHandler*> _msg_hanlers;

	};

	INIT_PLUGIN(MyPlugin);


	//===============================
	// 变量定义
	static Configuration s_cfg;


	//===============================
	// 功能实现

	void MyPlugin::initialize()
	{
		Output( "Initializing module demo01");

		s_cfg = Engine::configFile("demo01");

		s_cfg.load();

		int level = s_cfg.getIntValue("debug", "level", TelEngine::debugLevel());
		withDebugEnabler()->debugLevel(level);

		if (!m_initialized) {

			// 设置初始化标记，避免多次调用情况出现问题
			m_initialized = true;


			// 订阅消息处理
			YateMsgHandler* handler;

			// 引擎启动消息
			handler = new YateMsgHandler(MSG_ENGINE_START);
			handler->_handler = [this](Message& msg) {
				this->onEngineStart();
				return false;
			};
			Engine::install(handler);
			_msg_hanlers.push_back(handler);

			// 引擎退出消息
			handler = new YateMsgHandler(MSG_ENGINE_STOP);
			handler->_handler = [this](Message& msg) {
				this->onEngineStop();
				return false;
			};
			Engine::install(handler);
			_msg_hanlers.push_back(handler);

			int priority = s_cfg.getIntValue("general", "priority", 100);
			handler = new YateMsgHandler(MSG_YATE, priority);
			handler->_handler = [this](Message& msg) {
				return this->onYateMessage(msg);
			};
			Engine::install(handler);
			_msg_hanlers.push_back(handler);

			handler = new YateMsgHandler("demo01.cmd");
			handler->_handler = [this](Message& msg) {
				return this->onDemoMessage(msg);
			};
			Engine::install(handler);
			_msg_hanlers.push_back(handler);


		}

		// 调试消息处理
		int on = s_cfg.getBoolValue("debug", "on", false);
		if (on) {
			if (!_debug_hdl) {
				int priority = s_cfg.getIntValue("debug", "priority", 100);
				_debug_hdl = new YateMsgHandler("Yateshop.debug", priority);
				_debug_hdl->_handler = [this](Message& msg) {
					return this->onYateDebug(msg);
				};
				Engine::install(_debug_hdl);
			}
		}
		else {
			if (_debug_hdl) {
				Engine::uninstall(_debug_hdl);
				delete _debug_hdl;
				_debug_hdl = nullptr;
			}
		}


	}


	void MyPlugin::onEngineStart()
	{

		//S_INFO("onEngineStart, ***************************");
		//Y_WARN("onEngineStart, ***************************");

		//const String& shared = Engine::sharedPath();

		//const String& user = Engine::configPath(true);

		//const String& config = Engine::configPath(false);


	}


	void MyPlugin::onEngineStop()
	{
		//S_INFO( "onEngineStop ")  ;

	}


	bool MyPlugin::onYateMessage(Message& msg)
	{

		String Op = msg.getParam("Op");

		if (Op == "demo.01"){

			int what = msg.getIntValue("what");
			int arg1 = msg.getIntValue("arg1");
			int arg2 = msg.getIntValue("arg2");

			Y_INFO( fmt::format("demo1 what {}, arg1 {}, arg2 {}", what, arg1, arg2) );


			return true;
		}

		if (Op == "demo") {

			int what = msg.getIntValue("what");
			int arg1 = msg.getIntValue("arg1");
			int arg2 = msg.getIntValue("arg2");

			S_INFO("demo, ******");

			return true;
		}

		if (Op == "demo.all") {
			S_INFO("demo.all, ******");
			return false;
		}

		return false;
	}

	bool MyPlugin::onDemoMessage(Message& msg)
	{
		S_INFO("onDemoMessage");
		msg.setParam("hello", "yate");
		return true;
	}
		
	bool MyPlugin::onYateDebug(Message& msg)
	{

		return false;
	}


	bool MyPlugin::unload()
	{
		// 注销消息处理器，以支持动态卸载模块

		if (_debug_hdl) {
			Engine::uninstall(_debug_hdl);
			delete _debug_hdl;
			_debug_hdl = nullptr;
		}

		auto i = _msg_hanlers.begin();
		for (; i != _msg_hanlers.end(); i++) {
			Engine::uninstall(*i);
			delete* i;
		}
		_msg_hanlers.clear();

		return true;
	}


}

/*
* 支持模块内日志宏
*/

TelEngine::DebugEnabler * withDebugEnabler()
{
	return &__plugin;
}

/*
 *
 *	支持模块动态卸载接口
 *
*/
UNLOAD_PLUGIN(unloadNow)
{
	if (unloadNow) {
		// 动态卸载模块
		if (!__plugin.unload()) {
			S_INFO("unload module false, " << __plugin.name().safe());
			return false;
		}
		S_INFO("unload module, " << __plugin.name().safe());
		return true;
	}
	else {
		// 检测是否能够动态卸载
		return true;
	}
}
